use std::sync::{Arc,Mutex};
use std::thread;
use std::collections::HashMap;

#[macro_export]
macro_rules! parallel_map {
    ($nums:expr, $method:expr) => {
        {
            let mut result = Vec::new();
            let result_ = Arc::new(Mutex::new(HashMap::new()));
            let mut handles = vec![];
            let mut nums_=Vec::new();

            for t in $nums.into_iter() {
                let temp = Arc::clone(&result_);
                nums_.push(t);
                let handle = thread::spawn(move || {
                    let y = $method(t);
                    temp.lock().unwrap().insert(t, y);
                });
                handles.push(handle);
            }

            for handle in handles {
                handle.join().unwrap();
            }

            let result_map = result_.lock();
            for &t in &nums_ {
                if let Some(&v) = result_map.get(&t) {
                    result.push(v);
                }
            }
            result
        }
    };
}

fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6,7];
    let squares: Vec<i32> = parallel_map!(numbers, |x| x * x);
    for i in squares {
        println!("{}", i);
    }
}
